﻿using AvalonDock;
using ReflectionStudio.Classes;
using ReflectionStudio.Components.UserControls;
using ReflectionStudio.Core.Events;
using ReflectionStudio.LocalizationLibrary;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using WPFExcelReport.TranslationByMarkupExtension;
namespace WPFExcelReport
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class MainWindow : Fluent.RibbonWindow
    {
        #region ---------------------INIT--------------------- 
        public string LayoutFile
        {
            get { return ApplicationBase.LayoutFile; }
        }
        ApplicationBase ApplicationBase = new ApplicationBase();
        private System.Windows.Forms.Panel _panel;
        private Process _process;  
        /// <summary>
        /// Constructor
        /// </summary>
        public MainWindow()
        { 
            InitializeComponent();
            _panel = new System.Windows.Forms.Panel();
            Tracer.Verbose("MainWindow:MainWindow", "START");
            try
            {
                Tracer.Verbose("MainWindow:MainWindow", "Event attachement");
                #region----------------------------Original--------------------------------
                DocumentFactory.Instance.Initialize(this._dockingManager);
                TranslationManager.Instance.TranslationProvider = new ResxTranslationProvider("TranslationByMarkupExtension.Resources", Assembly.GetExecutingAssembly());
                //get the active documents events 
                _dockingManager.PropertyChanged += new PropertyChangedEventHandler(DockingManagerPropertyChanged);

                //get all states event changes from doc and panels
                DependencyPropertyDescriptor prop = DependencyPropertyDescriptor.FromProperty(
                                                    DockableContent.StatePropertyKey.DependencyProperty, typeof(DockableContent));

                prop.AddValueChanged(this._LogExplorerDock, OnPanelStateChanged);
                //prop.AddValueChanged(this._PropertyExplorerDock, OnPanelStateChanged);

                BindingView.Instance.Panels.Add(this._LogExplorerDock);
                //BindingView.Instance.Panels.Add(this._PropertyExplorerDock);
                //catch events
                EventDispatcher.Instance.OnStatusChange += new EventHandler<StatusEventArgs>(this.MainStatusBar.OnStatusChange);

                //forward also all changes to the log toolbox
                EventDispatcher.Instance.OnMessage += new EventHandler<MessageEventArgs>(_LogExplorerDock.OnMessage);

                //set the datacontext
                this.DataContext = BindingView.Instance;
                BindingView.Instance.UpdateView();
                #endregion
                LocalizationManager.AppLocalizationProviderType = typeof(VMLocalizationProvider);
                LocalizationManager.CurrentLanguage = (Language)"en";
                LocalizationManager.Initialize();
                ApplicationBase.LoadAssembly(Assembly.GetExecutingAssembly());
                ApplicationBase.Load();  
                SetUpUserMenu();
                DisplayHomeDocument();
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
            finally
            { 
                Tracer.Verbose("MainWindow:MainWindow", "END");
            }
        }
        private void btnCheUpdate_Click(object sender, RoutedEventArgs e)
        {
           
        }  
        void updater_Error(object sender, EventArgs e)
        {
           
        }
        #endregion 
        #region ---------------------DOCUMENT/PANEL---------------------

        private void DisplayHomeDocument()
        {
            string doctype = dicParamater["DocType"].ToString();
            ActivateReportByDocType(doctype);            
        }

        #endregion

        #region ---------------------DOCMANAGER EVENTS---------------------

        /// <summary>
        /// Have to use this event, because win.onload throw an exception
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _dockingManager_Loaded(object sender, RoutedEventArgs e)
        {
            Tracer.Verbose("MainWindow:_dockingManager_Loaded", "RestoreLayout");

            if (!File.Exists(LayoutFile))
                return;

            _dockingManager.RestoreLayout(LayoutFile);

            Tracer.Verbose("MainWindow:_dockingManager_Loaded", "RestoreLayout Ok");
        }

        void DockingManagerPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            //manage the active document
            if (e.PropertyName == "ActiveDocument" && _dockingManager.ActiveDocument != null)
            {
                Tracer.Verbose("MainWindow.DockingManagerPropertyChanged", "ActiveDocument property changed");

                // handle inactivation on document
                HandleInactiveDocument(ActiveDocument);

                // save the new active doc in the main window
                ActiveDocument = (DocumentContent)_dockingManager.ActiveDocument;

                // handle activation on document
                HandleActiveDocument(ActiveDocument);
            }
        }

        private void HandleActiveDocument(DocumentContent newDocument)
        {
            if (newDocument == null)
                return;

            Tracer.Verbose("MainWindow.HandleActiveDocument", "[{0}] '{1}' becomes active", DateTime.Now.ToLongTimeString(), newDocument.Title);

            //plug to zoom event handling if needed
            if (newDocument is ZoomDocument)
            {
                ZoomDocument zd = (ZoomDocument)newDocument;

                this.MainStatusBar.CanZoom = true;
                this.MainStatusBar.SliderZoom.Value = zd.Scale;

                //root status bar update to the document
                this.MainStatusBar.ZoomChanged += new EventHandler<ZoomRoutedEventArgs>(zd.OnZoomChanged);

                //root doc evet to the status bar
                zd.ZoomChanged += new ZoomDocument.ZoomChangedEventHandler(this.MainStatusBar.OnZoomChanged);
            }
            else

                this.MainStatusBar.CanZoom = false;//disable the zoom slider 

        }

        private void HandleInactiveDocument(DocumentContent previousDocument)
        {
            if (previousDocument == null)
                return;

            Tracer.Verbose("MainWindow.HandlePreviousActiveDocument", "[{0}] '{1}' becomes inactive",
                        DateTime.Now.ToLongTimeString(), previousDocument.Title);

            //remove the previous doc from event handling
            if (previousDocument is ZoomDocument)
            {
                ZoomDocument zd = (ZoomDocument)previousDocument;

                this.MainStatusBar.ZoomChanged -= new EventHandler<ZoomRoutedEventArgs>(zd.OnZoomChanged);
                zd.ZoomChanged -= new ZoomDocument.ZoomChangedEventHandler(this.MainStatusBar.OnZoomChanged);
            }
        }

        void OnPanelStateChanged(object sender, EventArgs e)
        {
            DockableContent content = sender as DockableContent;

            if (content.ContainerPane is DockablePane)
            {
                Tracer.Verbose("MainWindow.OnPanelStateChanged", "[{0}] '{1}' changed state to '{2}' (Anchor={3})",
                    DateTime.Now.ToLongTimeString(), content.Title, content.State, ((DockablePane)content.ContainerPane).Anchor);
            }
            else
            {
                Tracer.Verbose("MainWindow.OnPanelStateChanged", "[{0}] '{1}' changed state to '{2}'",
                    DateTime.Now.ToLongTimeString(), content.Title, content.State);
            }
        }

        #endregion

        #region========CONTAINER===============
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr SetParent(IntPtr hWndChild,
        IntPtr hWndNewParent);
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName,
        string lpWindowName);
        [DllImport("user32.dll")]
        static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        [DllImport("user32.dll", SetLastError = true)]
        static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("user32")]
        private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);

        private const int SWP_NOZORDER = 0x0004;
        private const int SWP_NOACTIVATE = 0x0010;
        private const int GWL_STYLE = -16;
        private const int WS_CAPTION = 0x00C00000;
        private const int WS_THICKFRAME = 0x00040000; 
 

        #endregion
         
        /// <summary>
        /// After closing the project and all opened document, release event hadlers
        /// and save the layout. See also Application
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OfficeWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Tracer.Verbose("MainWindow:OfficeWindow_Closing", "START");

            try
            { 
                if (_dockingManager != null)
                    _dockingManager.PropertyChanged -= new PropertyChangedEventHandler(DockingManagerPropertyChanged);

                _dockingManager.SaveLayout(LayoutFile);
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.StackTrace, ex);
            }
            finally
            {
                Tracer.Verbose("MainWindow:OfficeWindow_Closing", "END");
            }
        }

        /// <summary>
        /// Manage drag and drop of files onto the main window
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OfficeWindow_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] droppedFilePaths =
                e.Data.GetData(DataFormats.FileDrop, true) as string[];
            }
        }
        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            ApplicationBase.Quit();
            base.OnClosing(e);
            if (_process != null)
            {
                _process.Refresh();
                _process.Close();
            }
        }

        private void ResizeEmbeddedApp()
        {
            if (_process == null)
                return;

            SetWindowPos(_process.MainWindowHandle, IntPtr.Zero, 0, 0, (int)_panel.ClientSize.Width, (int)_panel.ClientSize.Height, SWP_NOZORDER | SWP_NOACTIVATE);
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            Size size = base.MeasureOverride(availableSize);
            ResizeEmbeddedApp();
            return size;
        }


    }
}
